package client

import (
	"encoding/json"
	"fmt"
	"gitee.com/taadis/xkcder/model"
	"io"
	"log"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"time"
)

type ComicNumber int

const (
	BaseUrl string = "https://xkcd.com"
	DefaultClientTimeout time.Duration = 30 * time.Second
	LatestComic ComicNumber = 0
)

// XkcdClient 是 xkcd 的客户端结构体
type XkcdClient struct {
	httpClient *http.Client
	baseUrl string
}

// NewClient 创建一个新的 xkcd 客户端实例
func NewClient() *XkcdClient  {
	return &XkcdClient{
		httpClient: &http.Client{
			Timeout:DefaultClientTimeout,
		},
		baseUrl:BaseUrl,
	}
}

// SetTimeout 覆盖了默认的超时设置
func (this *XkcdClient) SetTimeout(d time.Duration)  {
	this.httpClient.Timeout = d
}

// BuildUrl 根据提供的漫画编号构建需要的请求地址
func (this *XkcdClient) BuildUrl(comicId int) string  {
	if comicId <= 0{
		return fmt.Sprintf("%s/info.0.json", this.baseUrl)
	}
	return fmt.Sprintf("%s/%d/info.0.json", this.baseUrl, comicId)
}

// SaveToDisk 下载并保存漫画到本地
func (this *XkcdClient) SaveToDisk(url, savePath string) error  {
	resp, err := http.Get(url)
	if err != nil{
		return err
	}
	defer  resp.Body.Close()

	absPath, _ := filepath.Abs(savePath)
	filePath := fmt.Sprintf("%s/%s", absPath, path.Base(url))

	file, err := os.Create(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = io.Copy(file, resp.Body)
	if err != nil {
		return err
	}
	return nil
}

// Fetch 根据提供的漫画编号拉取漫画
func (this *XkcdClient) Fetch(comicId int, isSave bool) (*model.Comic, error)  {
	url := this.BuildUrl(comicId)
	response, err := this.httpClient.Get(url)
	if err != nil{
		return nil, err
	}
	defer response.Body.Close()


	comicResp := &model.ComicResponse{}
	err = json.NewDecoder(response.Body).Decode(comicResp)
	if err != nil{
		return nil, err
	}

	if isSave{
		 err = this.SaveToDisk(comicResp.Img, ".")
		 if err != nil{
		 	log.Println("保存漫画失败!")
		 }
	}
	return comicResp.Comic(), nil
}

